﻿using BasicFramework.Devices.DirectX9;
using BasicFramework.Helper;
using BasicFramework.Rendering.Primitives;
using SlimDX;
using SlimDX.Direct3D9;
using System;
using System.Diagnostics;

namespace BasicFramework.Rendering.Buffer.DirectX9
{
    public class DX9DynamicVertexBuffer<T> : DynamicPrimitiveBuffer<T> where T : struct ,IPrimitive
    {

        #region Fields

        private VertexBuffer vBuffer;
        private VertexDeclaration vDeclaration;
        private DX9DeviceContext internalContext;


        #endregion


        #region Properties



        #endregion


        #region Constructors

        public DX9DynamicVertexBuffer(DX9DeviceContext context)
        {
            if (context == null)
            {
                Logger.Error("No DeviceContext specified !");
                Debug.Fail("No DeviceContext specified !");
            }
            this.internalContext = context;
        }
        #endregion


        #region Events

        #endregion


        #region Methods

        internal override void FillBuffer()
        {
            DataStream stream = vBuffer.Lock(0, 0, LockFlags.Discard);
            stream.Seek(0, System.IO.SeekOrigin.Begin);
            try
            {
                stream.WriteRange(this.Primitives.ToArray());
            }
            catch (Exception ex)
            {
                Logger.Exception(ex);
            }
            finally
            {
                this.vBuffer.Unlock();
            }
        }

        internal override void SetPrimitiveDeclaration()
        {
            this.vDeclaration = new VertexDeclaration(this.internalContext.Device, new T().GetVertexElements);
        }


        internal override void SetBufferInternal(int stream)
        {
            this.internalContext.Device.SetStreamSource(stream, vBuffer, 0, new T().GetSize);
            this.internalContext.Device.VertexDeclaration = vDeclaration;
        }

        internal override void ResizeBuffer(int newSize)
        {
            if (this.internalContext == null)
            {
                Logger.Error("No Device Context specified !");
                Debug.Fail("No Device Context specified !");
                return;
            }
            if (vBuffer != null)
            {
                this.vBuffer.Dispose();
            }

            // Create a new Vertex Buffer
            this.vBuffer = new VertexBuffer(
                this.internalContext.Device,
                newSize,
                Usage.Dynamic | Usage.WriteOnly,
                VertexFormat.None,
                Pool.Default
            );
        }

        internal override void DisposeBuffer()
        {
            if (this.vBuffer != null)
            {
                this.vBuffer.Dispose();
            }
            if (this.vDeclaration != null)
            {
                this.vDeclaration.Dispose();
            }

        }


        #endregion

    }
}
